/**
 * JFClientConnecte.java    23/03/2012
 */

package l3.info.projetJava.client;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.sql.Date;
import java.sql.Time;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.ScrollPaneConstants;

import org.apache.log4j.Logger;

import l3.info.projetJava.client.JDAPropos;
import l3.info.projetJava.client.JDAjoutSuivi;
import l3.info.projetJava.client.JFAuthentification;
import l3.info.projetJava.serveur.DAOMessage;
import l3.info.projetJava.utilitaires.OperationChaine;

/**
 * Représente la JFrame lorsque l'utilisateur
 * est connecté
 * @author Loïc Martinez
 * @version 1.0
 */

public class JFClientConnecte extends JFrame implements ActionListener,
MouseListener {

    /** Constantes */
    private static final String TITRE = "MessageFolder : ";
    private static final String DCNX = "Déconnexion";
    private static final String QUITTER = "Quitter";
    private static final String AJOUT = "Ajout suivi";
    private static final String FICHIER = "Fichier";
    private static final String AIDE = "Aide";
    private static final String APROPOS = "A propos...";
    private static final String UTILISATEURS_SUIVIS = "Utilisateurs suivis";
    private static final String MSG_ECRIT_PAR = "Messages écrits par ";
    private static final int LARGEUR_PAN_BOUTON = 50;
    private static final int HAUTEUR_PAN_BOUTON = 100;
    private static final int ABSCISSE = 250;
    private static final int ORDONNEE = 100;
    private static final int  LARGEUR = 685;
    private static final int HAUTEUR = 600; // 565; +35
    private static final Dimension SCROLL_SIZE = new Dimension(140, 447);
    private static final Dimension DIMENSION_PG = new Dimension(140, 400);
    private static final Dimension MIN_DIMENSION_PANEL =
            new Dimension(343, 300);
    private static final Color BACKGROUND_COLOR = new Color(255, 255, 255);
    private static final String DEBUT_DATE = "Date min ";
    private static final String FIN_DATE = " Date max ";
    private static final JLabel debutDate = new JLabel(DEBUT_DATE);
    private static final JLabel finDate = new JLabel(FIN_DATE);
    private static final String DATE = "OK";
    private static final int NB_DISPLAY_MESSAGES = 5;

    /** Notre pseudo */
    private String myPseudo;

    /** Les JPanel de gauche et de droite */
    private JPanel panelGauche, panelDroite, buttonPane, datePane;

    /** splitPane pour séparer la droite et la gauche,
     *  splitPane2 pour avoir une partie en bas (panelBouton)
     */
    private JSplitPane splitPane,splitPane2;

    /** Le JPanel pour les boutons (en bas de la fenêtre) */
    private JPanel panelBouton;

    /** Les 3 boutons de la JFrame */
    private JButton boutonEcrire, boutonAjouter, boutonSupprimer,
    boutonPrecedent, boutonSuivant, boutonDate;

    /** La liste des personnes suivies */
    private JList list;

    /** Permet d'avoir une barre de scrolling verticale
     *  pour les personnes suivies et les messages de la personne
     */
    private JScrollPane scroll, scrollAreaMe, scrollAreaOthers;

    /** Pour l'affichage des messages */
    private JTextArea areaMe, areaOthers;

    /** Pour pouvoir modifier la liste des utilisateurs */
    private DefaultListModel model;

    /** La barre Fichier etc. */
    private JMenuBar menuBar;

    /** Les différents menus (Fichier, Aide etc.) */
    private JMenu menuFichier;
    private JMenu menuAide;
    private JMenuItem menuAjoutSuivi;
    private JMenuItem menuDeconnexion;
    private JMenuItem menuQuitter;
    private JMenuItem menuAPropos;

    /** Menu pour chaque élément de la liste */
    private JPopupMenu menuList;
    private JMenuItem menuListItem;

    /** La Map des utilisateurs suivis, avec leur
     * numUtilisateur et leur pseudo
     */
    private Map<Integer, String> utilisateurSuivi;

    /** Mon numUtilisateur */
    private int myId;

    /** Champs des dates */
    private JFormattedTextField dateField1, dateField2;

    /** Précédent et suivant */
    private ImageIcon previous, next;

    /** Réseau RMI */
    private RequetesClient reqClient;

    /** Onglet */
    private JTabbedPane onglet;

    /** Messages de moi et des autres */
    List<Message> myMessages, othersMessages;

    /** Index du nombre de messages à afficher */
    int indexMessagesMe = 0, indexMessagesOthers = 0;

    /** Dates entrées */
    String dateValueMe1 = "", dateValueMe2 = "",
            dateValueOthers1 = "", dateValueOthers2 = "";

    /** Sauvegarde des dateValue */
    private String dateValueMeMax = null, dateValueMeMin = null,
            dateValueOthersMax = null, dateValueOthersMin = null;

    /** Logger */
    private static Logger logger = Logger.getLogger(JFClientConnecte.class);
    
    /**
     * Constructeur par défaut
     */
    public JFClientConnecte(Utilisateur u) {
        onglet = new JTabbedPane();
        myMessages = new ArrayList<Message>();
        othersMessages = new ArrayList<Message>();
        myId = u.getId();
        myPseudo = u.getPseudo();
        utilisateurSuivi = new HashMap<Integer, String>();
        model = new DefaultListModel();
        if (u.getUtilisateurSuivi().size() > 0) {
            Iterator<Integer> i = u.getUtilisateurSuivi().keySet().iterator();
            while (i.hasNext()) {
                Integer utilisateurNum = i.next();
                String pseudo = u.getUtilisateurSuivi().get(utilisateurNum);
                utilisateurSuivi.put(utilisateurNum, pseudo);
                // System.out.println(utilisateurNum + " " + pseudo);
            }
        }
        setProperties(u.getUtilisateurSuivi());
    }

    /**
     * Applique les propriétés pour la JFrame dont on hérite
     * @param utilisateurSuivi
     */
    public void setProperties(Map<Integer, String> utilisateurSuivi) {
        setTitle(TITRE + myPseudo);
        setBounds(ABSCISSE, ORDONNEE, LARGEUR, HAUTEUR);
        setResizable(false);
        getContentPane().setLayout(new BorderLayout());
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        fillJList(utilisateurSuivi);
        setComponents();
        setVisible(true);
    }

    /**
     * Ajoute le menu Fichier, Options, Aide...
     */
    private void addMenuBar() {
        menuBar = new JMenuBar();
        menuFichier = new JMenu(FICHIER);
        menuBar.add(menuFichier);

        menuAide = new JMenu(AIDE);
        menuBar.add(menuAide);

        setJMenuBar(menuBar);

        menuAjoutSuivi = new JMenuItem(AJOUT);
        menuFichier.add(menuAjoutSuivi);
        menuAjoutSuivi.addActionListener(this);

        menuDeconnexion = new JMenuItem(DCNX);
        menuFichier.add(menuDeconnexion);
        menuDeconnexion.addActionListener(this);

        menuQuitter = new JMenuItem(QUITTER);
        menuFichier.add(menuQuitter);
        menuQuitter.addActionListener(this);

        menuAPropos = new JMenuItem(APROPOS);
        menuAide.add(menuAPropos);
        menuAPropos.addActionListener(this);
    }

    /**
     * Place les composants dans la JFrame
     */
    @SuppressWarnings("serial")
    public void setComponents() {
        // On ajoute la barre de menus
        addMenuBar();

        // On créé et modifie le panel de gauche (utilisateurs)
        panelGauche = new JPanel(new FlowLayout());
        panelGauche.setBackground(BACKGROUND_COLOR);
        panelGauche.setLayout(new FlowLayout(FlowLayout.CENTER));

        panelGauche.setBorder(BorderFactory.createCompoundBorder(
                BorderFactory.createTitledBorder(UTILISATEURS_SUIVIS),
                BorderFactory.createEmptyBorder(10, 10, 10, 10)));

        panelGauche.setPreferredSize(DIMENSION_PG);

        // On créé et modifie le panel de droite (messages)
        panelDroite = new JPanel(new FlowLayout());

        panelDroite.setLayout(new BoxLayout(panelDroite, BoxLayout.Y_AXIS));
        panelDroite.setBorder(BorderFactory.createCompoundBorder
                (BorderFactory.createTitledBorder
                        (MSG_ECRIT_PAR + myPseudo),
                        BorderFactory.createEmptyBorder(1, 1, 1, 1)));

        panelDroite.setBackground(BACKGROUND_COLOR);

        // Permet de ne pas pouvoir redimensionner les splitPane
        panelDroite.setMinimumSize(new Dimension(MIN_DIMENSION_PANEL));
        panelGauche.setMinimumSize(new Dimension(MIN_DIMENSION_PANEL));

        // Contiendra les messages
        areaMe = new JTextArea();

        // On ne peut pas modifier le texte dedans
        areaMe.setEditable(false);

        // Contiendra les messages
        areaOthers = new JTextArea();

        // On ne peut pas modifier le texte dedans
        areaOthers.setEditable(false);

        // On y ajoute la barre de scrolling
        scrollAreaMe = new JScrollPane(areaMe);
        scrollAreaMe.setPreferredSize(new Dimension(100, 350));
        scrollAreaMe.setVerticalScrollBarPolicy(
                JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

        scrollAreaOthers = new JScrollPane(areaOthers);
        scrollAreaOthers.setPreferredSize(new Dimension(100, 350));
        scrollAreaOthers.setVerticalScrollBarPolicy(
                JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

        onglet.addTab("Mes messages", null, scrollAreaMe, null);
        onglet.addTab("Autres utilisateurs", null, scrollAreaOthers, null);

        panelDroite.add(onglet);

        datePane = new JPanel(new FlowLayout());
        //datePane.setPreferredSize(new Dimension(10, 10));
        datePane.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 50));
        datePane.add(Box.createHorizontalGlue());
        datePane.add(Box.createRigidArea(new Dimension(10, 10)));

        datePane.add(debutDate);

        dateField1 = new JFormattedTextField(
                new SimpleDateFormat("dd/MM/yyyy")) {
            protected void processFocusEvent(FocusEvent event) {

                String date = dateField1.getText().trim();

                super.processFocusEvent(event);
                SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
                try {
                    // Si la Date n'est pas bonne, on rentre dans
                    // le bloc catch et on efface le JFormattedTextField
                    sdf.parse(date);
                } catch (ParseException ex) {
                    dateField1.setText("");
                }
            }  
        };
        dateField1.setPreferredSize(new Dimension(70, 23));

        datePane.add(dateField1);

        datePane.add(finDate);

        dateField2 = new JFormattedTextField(
                new SimpleDateFormat("dd/MM/yyyy")) {
            protected void processFocusEvent(FocusEvent event) {

                String date = dateField2.getText().trim();

                super.processFocusEvent(event);
                SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
                try {
                    // Si la Date n'est pas bonne, on rentre dans
                    // le bloc catch et on efface le JFormattedTextField
                    sdf.parse(date);
                } catch (ParseException ex) {
                    dateField2.setText("");
                }
            }  
        };
        dateField2.setPreferredSize(new Dimension(70, 23));

        datePane.add(dateField2);

        datePane.add(new JLabel(" "));

        boutonDate = new JButton(DATE);
        boutonDate.addActionListener(this);

        datePane.add(boutonDate);

        panelDroite.add(datePane);

        //Lay out the buttons from left to right.
        buttonPane = new JPanel(new FlowLayout());
        //buttonPane.setPreferredSize(new Dimension(10, 10));
        buttonPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 60));
        buttonPane.add(Box.createHorizontalGlue());
        buttonPane.add(Box.createRigidArea(new Dimension(10, 10)));

        BufferedImage myPicture;
        try {
            myPicture = ImageIO.read
                    (JFAuthentification.class.getResource
                            ("pictures/precedent.png"));
            previous = new ImageIcon(myPicture);

            myPicture = ImageIO.read
                    (JFAuthentification.class.getResource
                            ("pictures/suivant.png"));

            next = new ImageIcon(myPicture);
        } catch (IOException e) {
            logger.error("JFClientConnecte.setComponents() : IOException");
        }

        boutonPrecedent = new JButton(previous);
        boutonPrecedent.setPreferredSize(new Dimension(30, 30));
        boutonPrecedent.addActionListener(this);

        boutonSuivant = new JButton(next);
        boutonSuivant.setPreferredSize(new Dimension(30, 30));
        boutonSuivant.addActionListener(this);

        buttonPane.add(boutonPrecedent);
        buttonPane.add(boutonSuivant);

        panelDroite.add(buttonPane);

        // On initialise la JList avec la liste des utilisateurs
        list = new JList(model);

        // On ne peut sélectionner qu'un seul pseudo à la fois
        list.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        list.setFixedCellHeight(27);
        DefaultListCellRenderer centerRenderer = new DefaultListCellRenderer();
        centerRenderer.setHorizontalAlignment(JLabel.CENTER);
        list.setCellRenderer(centerRenderer);
        list.addMouseListener(this);

        // On y ajoute aussi la barre de scrolling
        scroll = new JScrollPane(list);
        scroll.setPreferredSize(SCROLL_SIZE);
        scroll.setHorizontalScrollBarPolicy(
                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

        // On ajoute le scroll au panel gauche
        panelGauche.add(scroll);

        // Le splitPane avec une separation horizontale (barre à la verticale)
        splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panelGauche,
                panelDroite);

        // Place la barre de séparation a 150 px
        splitPane.setDividerLocation(150);

        // On ajoute les différents boutons
        panelBouton = new JPanel(new BorderLayout());
        panelBouton.setLayout(null);
        panelBouton.setSize(LARGEUR_PAN_BOUTON, HAUTEUR_PAN_BOUTON);

        boutonEcrire = new JButton ("Ecrire");
        boutonEcrire.setBounds(390, 15, 90, 25);
        panelBouton.add(boutonEcrire);

        boutonAjouter = new JButton ("Ajouter");
        boutonAjouter.setBounds(485, 15, 90, 25);
        boutonAjouter.addActionListener(this);

        panelBouton.add(boutonAjouter);
        boutonEcrire.addActionListener(this);

        // Utilisation d'une balise html car texte trop long dans
        // le JButton
        boutonSupprimer = new JButton ("<html>Supprimer</html>");
        boutonSupprimer.setBounds(580, 15, 90, 25);
        boutonSupprimer.setEnabled(false);
        boutonSupprimer.addActionListener(this);
        panelBouton.add(boutonSupprimer);

        // Ajout du popupMenu à chaque élément de la Jlist
        // pour pouvoir supprimer l'utilisateur sélectionné
        menuList = new JPopupMenu();
        menuListItem = new JMenuItem("Supprimer");
        menuListItem.addActionListener(this);
        menuList.add(menuListItem);
        scroll.setComponentPopupMenu(menuList);

        // On ajoute le panneau final qui contient tous les autres
        splitPane2 = new JSplitPane(JSplitPane.VERTICAL_SPLIT, splitPane,
                panelBouton);
        splitPane2.setDividerLocation(490);

        add(splitPane2);

        // Affiche les 5 premiers messages me correspondant à partir du
        // 1er message
        afficheAndFillMessages(myMessages, indexMessagesMe,
                NB_DISPLAY_MESSAGES, myId, areaMe);

        // On ajoute un mouse listener sur le clic de souris
        // sur un des onglets
        onglet.addMouseListener(new java.awt.event.MouseAdapter()
        {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                // On vient de cliquer sur "Mes messages"
                if (onglet.getTitleAt(
                        onglet.getSelectedIndex()).equals("Mes messages")) {
                    panelDroite.setBorder(BorderFactory.createCompoundBorder
                            (BorderFactory.createTitledBorder
                                    (MSG_ECRIT_PAR + myPseudo),
                                    BorderFactory.createEmptyBorder(1, 1, 1, 1)));

                    dateField1.setText(dateValueMe1);
                    dateField2.setText(dateValueMe2);
                } else if (onglet.getTitleAt(
                        onglet.getSelectedIndex()).equals(
                                "Autres utilisateurs")) {

                    if (list.getSelectedValue() == null) {
                        panelDroite.setBorder(BorderFactory.createCompoundBorder
                                (BorderFactory.createTitledBorder
                                        ("Pas de personne suivie sélectionnée"),
                                        BorderFactory.createEmptyBorder(1, 1, 1, 1)));
                    } else {
                        panelDroite.setBorder(BorderFactory.createCompoundBorder
                                (BorderFactory.createTitledBorder
                                        (MSG_ECRIT_PAR + list.getSelectedValue()),
                                        BorderFactory.createEmptyBorder(1, 1, 1, 1)));
                    }
                    // On vient de cliquer sur Autres utilisateurs
                    dateField1.setText(dateValueOthers1);
                    dateField2.setText(dateValueOthers2);
                }
            }
        });
    }

    /**
     * Initialise la JList
     * @param utilisateurSuivi, les utilisateurs déjà suivis
     */
    public void fillJList(Map<Integer, String> utilisateurSuivi) {
        if (utilisateurSuivi.size() > 0) {
            for (String pseudo : utilisateurSuivi.values()) {
                model.addElement(pseudo);
            }
        }
    }

    /**
     * @return le numUser du pseudo sélectionnée
     */
    private int getNumUserSelectedJList() {
        int numUser = -1;
        for (Entry<Integer, String> entry : 
            utilisateurSuivi.entrySet()) {
            if (entry.getValue().equals(
                    list.getSelectedValue().toString())) {
                numUser = entry.getKey();
            }
        }
        return numUser;
    }

    /**
     * Permet d'afficher les messages de l'utilisateur
     */
    public void afficheAndFillMessages
    (List<Message> m, int index, int nbMessages, int id, JTextArea textArea) {
        try {
            RequetesClient rClient = new RequetesClient();
            m = rClient.recupererMessages(
                    index, nbMessages, id);
            afficheMessages(m, textArea);
        } catch (NotBoundException ex) {
            new JDError("Problème de communication serveur. Exit");
            logger.error("JFClientConnecte.afficheAndFillMessages() : NotBoundException");
            dispose();
        } catch (RemoteException ex) {
            new JDError("Problème de communication serveur. Exit");
            logger.error("JFClientConnecte.afficheAndFillMessages() : RemoteException");
            dispose();
        }
    }

    /**
     * Permet d'afficher les messages de l'utilisateur
     */
    public void afficheAndFillMessages
    (List<Message> m, int index, int nbMessages, int id, JTextArea textArea,
            String date1, String date2) {
        try {
            RequetesClient rClient = new RequetesClient();
            m = rClient.recupererMessages(
                    index, nbMessages, id, date1, date2);
            afficheMessages(m, textArea);
        } catch (NotBoundException ex) {
            new JDError("Problème de communication serveur. Exit");
            logger.error("JFClientConnecte.afficheAndFillMessages() : NotBoundException");
            dispose();
        } catch (RemoteException ex) {
            new JDError("Problème de communication serveur. Exit");
            logger.error("JFClientConnecte.afficheAndFillMessages() : RemoteException");
            dispose();
        }
    }

    /**
     * Permet de savoir si l'id entré est correct
     * @param id, l'id entré
     */
    private static void checkIdEntered(int id) {
        // Ajout de l'utilisateur, si déjà suivi ou
        // n'existe pas, afficher une JDialog d'erreur
        if (id == -1) {
            // Erreur
            new JDError("Utilisateur déjà suivi !");
        } else if (id == -2) {
            new JDError("Vous ne pouvez pas vous suivre !");
        } else if (id == -3) {
            // N'existe pas dans la base de données
            new JDError("Cet utilisateur n'existe pas !");
        }
    }

    /**
     * Permet d'ajouter une personne à suivre
     */
    private void ajoutIdASuivre() {

        List<Integer> listNumutilisateurSuivi = new ArrayList<Integer>();

        // On ajoute les numUtilisateur suivis
        for (int numUtilisateur : utilisateurSuivi.keySet()) {
            listNumutilisateurSuivi.add(numUtilisateur);
        }

        JDAjoutSuivi JDAjout = new JDAjoutSuivi(myId, listNumutilisateurSuivi);

        // On a annulé dans JDAjoutSuivi
        if (JDAjout.getIdAndPseudo().size() != 0) {

            Map<Integer, String> idAndPseudo =
                    JDAjout.getIdAndPseudo();

            int numUtilisateurSuivi = idAndPseudo.keySet().iterator().next();

            // on regarde la valeur retounée
            checkIdEntered(numUtilisateurSuivi);

            String pseudoSuivi = idAndPseudo.values().iterator().next();

            if (pseudoSuivi != null) {
                // On l'ajoute à la liste des utilisateurs suivis
                // et à la JList
                utilisateurSuivi.put(numUtilisateurSuivi, pseudoSuivi);
                model.addElement(pseudoSuivi);
            }
        }
    }

    /**
     * Permet de supprimer l'utilisateur sélectionné
     * dans la JList ainsi que dans la base de données
     * @param numUserToDelete, le numéro de l'utilisateur
     *        à supprimer
     */
    private void removeUser(int numUserToDelete) {
        try {
            RequetesClient rClient = new RequetesClient();

            rClient.removeNumUtilisateur(myId, numUserToDelete);
            model.remove(model.indexOf(list.getSelectedValue()));

            // On l'enlève de la HashMap
            utilisateurSuivi.remove(numUserToDelete);

            // On reset l'affiche des messages
            areaOthers.setText("");

        } catch (NotBoundException ex) {
            new JDError("Problème de communication serveur. Exit");
            logger.error("JFClientConnecte.removeUser() : NotBoundException");
            dispose();
        } catch (RemoteException ex) {
            new JDError("Problème de communication serveur. Exit");
            logger.error("JFClientConnecte.removeUser() : RemoteException");
            dispose();
        }
    }

    /**
     * Permet d'afficher des messages dans un areaText
     * @param messages les messages à afficher
     * @param areatText le textArea où les afficher
     */
    private void afficheMessages(List<Message> messages, JTextArea textArea) {
        String text = "";
        for (Message message : messages) {
            text += "Ecrit le " + message.getDateCreation()
                    + "\n\n" + message.getMessage()
                    + "\n             ===================================="
                    + "\n";
        }

        textArea.setText(text);
        textArea.setCaretPosition(0);
    }

    /**
     * Lorsqu'un évènement est déclenché
     * @param ev, l'évènement
     */
    public void actionPerformed(ActionEvent ev) {
        // Appui sur déconnexion
        if (ev.getSource() == menuDeconnexion) {
            // Enlever l'utilisateur connecté grâce au booléen,
            // etc (passer le user à null ?)
            new JFAuthentification();
            dispose();
        } else if (ev.getSource() == menuAjoutSuivi) {
            ajoutIdASuivre();
        } else if (ev.getSource() == menuQuitter) {
            // Enlever l'utilisateur connecté grâce au booléen, etc
            dispose();
        } else if (ev.getSource() == menuAPropos) {
            new JDAPropos("Loïc Martinez");
        } else if (ev.getSource() == boutonAjouter) {
            ajoutIdASuivre();
        } else if (ev.getSource() == boutonEcrire) {
            traiteBoutonEcrire();
        } else if (ev.getSource() == boutonSupprimer) {
            traiteBoutonSupprimer();
        } else if (ev.getSource() == menuListItem) { // Supprimer
            traiteBoutonSupprimer();
        } else if (ev.getSource() == boutonPrecedent) {
            traiteBoutonPrecedent();
        } else if (ev.getSource() == boutonSuivant) {
            traiteBoutonSuivant();
        } else if (ev.getSource() == boutonDate) {
            traiteBoutonDate();
        }
    }

    /**
     * Si appui sur le bouton Ecrire
     */
    public void traiteBoutonEcrire() {

        JDEcrireMessage jdMess = new JDEcrireMessage();

        // Si le texte est non-vide, on fait le INSERT INTO dans la
        // base de données
        if (jdMess.isEnvoye()
                && ! jdMess.getText().equals("")) {
            // Et on réactualise la liste des messages de l'utilisateur
            // dans l'interface graphique
            try {
                reqClient = new RequetesClient();
                reqClient.envoyerMessage(myId, jdMess.getText());

                indexMessagesMe = 0;

                // On recharge les messages
                afficheAndFillMessages(myMessages, indexMessagesMe,
                        NB_DISPLAY_MESSAGES, myId, areaMe);
            } catch (java.rmi.NotBoundException ex) {
                new JDError("Problème de communication serveur. Exit");
                logger.error("JFClientConnecte.traiteBoutonEcrire() : NotBoundException");
                dispose();
            } catch (java.lang.NullPointerException ex) {
                new JDError("Problème de communication serveur. Exit");
                logger.error("JFClientConnecte.traiteBoutonEcrire() : NullPointerException");
                dispose();
            } catch (RemoteException ex) {
                new JDError("Problème de communication serveur. Exit");
                logger.error("JFClientConnecte.traiteBoutonEcrire() : RemoteException");
                dispose();
            }
        }
    }
    
    /**
     * Si appui sur le bouton supprimer
     * ou sur le supprimer de la liste
     */
    public void traiteBoutonSupprimer() {

        // On récupère le numUtilisateur associé au pseudo
        int numUtilisateurASupprimer = getNumUserSelectedJList();

        removeUser(numUtilisateurASupprimer);

        panelDroite.setBorder(BorderFactory.createCompoundBorder
                (BorderFactory.createTitledBorder
                        ("Pas de personne suivie sélectionnée"),
                        BorderFactory.createEmptyBorder(1, 1, 1, 1)));

        // On RAZ l'index
        indexMessagesOthers = 0;
        dateValueOthers1 = "";
        dateValueOthers2 = "";
        dateValueOthersMin = null;
        dateValueOthersMax = null;

    }
    
    /**
     * Si appui sur le bouton précédent
     */
    public void traiteBoutonPrecedent() {
     // RequetesClient rc = new RequetesClient();
        if (onglet.getSelectedIndex() == 0
                && indexMessagesMe > 0) {
            // On décrémente l'index
            indexMessagesMe--;

            if (dateValueMeMin != null
                    && dateValueMeMax != null) {
                // Les 2 dates ont été renseignées lors du
                // dernier appui sur le bouton
                afficheAndFillMessages(myMessages, indexMessagesMe * NB_DISPLAY_MESSAGES,
                        NB_DISPLAY_MESSAGES, myId, areaMe, dateValueMe1, dateValueMe2);
            } else if (dateValueMeMin == null
                    && dateValueMeMax != null) {

                // Juste la dateValueMax a été renseignée lors du
                // dernier appui sur le bouton
                afficheAndFillMessages(myMessages, indexMessagesMe * NB_DISPLAY_MESSAGES,
                        NB_DISPLAY_MESSAGES, myId, areaMe, null, dateValueMe2);
            } else if (dateValueMeMin != null 
                    && dateValueMeMax == null) {

                // Juste la dateValueMeMin a été renseignée lors du
                // dernier appui sur le bouton
                afficheAndFillMessages(myMessages, indexMessagesMe * NB_DISPLAY_MESSAGES,
                        NB_DISPLAY_MESSAGES, myId, areaMe, dateValueMe1, null);

            } else { // Les 2 n'étaient pas renseignées
                // On regarde si c'est mes messages qu'il faut regarder
                // ou ceux de quelqu'un de sélectionné
                // 0 -> Mes messages
                // 1 -> Autres utilisateurs
                afficheAndFillMessages(myMessages, indexMessagesMe * NB_DISPLAY_MESSAGES,
                        NB_DISPLAY_MESSAGES, myId, areaMe);
            }
        } else if (onglet.getSelectedIndex() == 1
                && indexMessagesOthers > 0) {
            // On récupère le numUtilisateur associé au pseudo
            int numUser = getNumUserSelectedJList();

            indexMessagesOthers--;

            if (dateValueOthersMin != null
                    && dateValueOthersMax != null) {
                // Les 2 dates ont été renseignées lors du
                // dernier appui sur le bouton
                afficheAndFillMessages(othersMessages, indexMessagesOthers * NB_DISPLAY_MESSAGES,
                        NB_DISPLAY_MESSAGES, numUser, areaOthers,
                        dateValueOthers1, dateValueOthers2);

            } else if (dateValueOthersMin == null
                    && dateValueOthersMax != null) {

                // Juste la dateValueMax a été renseignée lors du
                // dernier appui sur le bouton
                afficheAndFillMessages(othersMessages, indexMessagesOthers * NB_DISPLAY_MESSAGES,
                        NB_DISPLAY_MESSAGES, numUser, areaOthers,
                        null, dateValueOthers2);
            } else if (dateValueOthersMin != null 
                    && dateValueOthersMax == null) {

                // Juste la dateValueMeMin a été renseignée lors du
                // dernier appui sur le bouton
                afficheAndFillMessages(othersMessages, indexMessagesOthers * NB_DISPLAY_MESSAGES,
                        NB_DISPLAY_MESSAGES, numUser, areaOthers,
                        dateValueOthers1, null);

            } else { // Les 2 n'étaient pas renseignées
                // On regarde si c'est mes messages qu'il faut regarder
                // ou ceux de quelqu'un de sélectionné
                // 0 -> Mes messages
                // 1 -> Autres utilisateurs
                afficheAndFillMessages(othersMessages, indexMessagesOthers * NB_DISPLAY_MESSAGES,
                        NB_DISPLAY_MESSAGES, numUser, areaOthers);
            }
        }
    }
    
    /**
     * Si appui sur le bouton suivant
     */
    public void traiteBoutonSuivant() {
        try {
            RequetesClient rc = new RequetesClient();
            // On regarde si c'est mes messages qu'il faut regarder
            // ou ceux de quelqu'un de sélectionné
            // 0 -> Mes messages
            // 1 -> Autres utilisateurs
            if (onglet.getSelectedIndex() == 0
                    && dateValueMeMin == null
                    && dateValueMeMax == null) {
                // Aucun des 2 champs n'était renseignée
                // avant l'appui sur le bouton date
                // On regarde s'il y a des prochains messages
                if (rc.numberProchainsMessages(
                        (indexMessagesMe +1) * NB_DISPLAY_MESSAGES,
                        NB_DISPLAY_MESSAGES, myId) == DAOMessage.MESSAGES_YET) {

                    indexMessagesMe++;

                    afficheAndFillMessages(myMessages, indexMessagesMe * NB_DISPLAY_MESSAGES,
                            NB_DISPLAY_MESSAGES, myId, areaMe);
                }
            } else if (onglet.getSelectedIndex() == 0
                    && dateValueMeMin != null
                    && dateValueMeMax != null) {
                // Les 2 dates ont été renseignées lors du
                // dernier appui sur le bouton
                if (rc.numberProchainsMessages(
                        (indexMessagesMe +1) * NB_DISPLAY_MESSAGES,
                        NB_DISPLAY_MESSAGES, myId,
                        dateValueMe1, dateValueMe2) == DAOMessage.MESSAGES_YET) {

                    indexMessagesMe++;

                    afficheAndFillMessages(myMessages, indexMessagesMe * NB_DISPLAY_MESSAGES,
                            NB_DISPLAY_MESSAGES, myId, areaMe, dateValueMe1, dateValueMe2);
                }
            } else if (onglet.getSelectedIndex() == 0
                    && dateValueMeMin != null
                    && dateValueMeMax == null) {
                // Juste la dateValueMin a été renseignée lors du
                // dernier appui sur le bouton
                if (rc.numberProchainsMessages(
                        (indexMessagesMe +1) * NB_DISPLAY_MESSAGES,
                        NB_DISPLAY_MESSAGES, myId,
                        dateValueMe1, null) == DAOMessage.MESSAGES_YET) {

                    indexMessagesMe++;

                    afficheAndFillMessages(myMessages, indexMessagesMe * NB_DISPLAY_MESSAGES,
                            NB_DISPLAY_MESSAGES, myId, areaMe, dateValueMe1, null);
                }
            } else if (onglet.getSelectedIndex() == 0
                    && dateValueMeMin == null
                    && dateValueMeMax != null) {
                // Juste la dateValueMax a été renseignée lors du
                // dernier appui sur le bouton
                if (rc.numberProchainsMessages(
                        (indexMessagesMe +1) * NB_DISPLAY_MESSAGES,
                        NB_DISPLAY_MESSAGES, myId,
                        null, dateValueMe2) == DAOMessage.MESSAGES_YET) {

                    indexMessagesMe++;

                    afficheAndFillMessages(myMessages, indexMessagesMe * NB_DISPLAY_MESSAGES,
                            NB_DISPLAY_MESSAGES, myId, areaMe, null, dateValueMe2);
                }
            } else if (onglet.getSelectedIndex() == 1
                    && list.getSelectedValue() != null) {

                // On récupère le numUtilisateur associé au pseudo
                int numUser = getNumUserSelectedJList();

                // Aucun des 2 champs n'était renseignée
                // avant l'appui sur le bouton date
                // On regarde s'il y a des prochains messages
                if (dateValueOthersMin == null
                        && dateValueOthersMax == null
                        && rc.numberProchainsMessages(
                                (indexMessagesOthers +1) * NB_DISPLAY_MESSAGES,
                                NB_DISPLAY_MESSAGES, numUser) == DAOMessage.MESSAGES_YET) {

                    indexMessagesOthers++;

                    afficheAndFillMessages(othersMessages, indexMessagesOthers * NB_DISPLAY_MESSAGES,
                            NB_DISPLAY_MESSAGES, numUser, areaOthers);
                } else if (dateValueOthersMin != null
                        && dateValueOthersMax != null
                        // Les 2 dates ont été renseignées lors du
                        // dernier appui sur le bouton
                        && rc.numberProchainsMessages(
                                (indexMessagesOthers +1) * NB_DISPLAY_MESSAGES,
                                NB_DISPLAY_MESSAGES, numUser,
                                dateValueOthers1, dateValueOthers2) == DAOMessage.MESSAGES_YET) {

                    indexMessagesOthers++;

                    afficheAndFillMessages(othersMessages, indexMessagesOthers * NB_DISPLAY_MESSAGES,
                            NB_DISPLAY_MESSAGES, numUser, areaOthers,
                            dateValueOthers1, dateValueOthers2);

                } else if (dateValueOthersMin != null
                        && dateValueOthersMax == null
                        // Juste la dateValueMin a été renseignée lors du
                        // dernier appui sur le bouton
                        && rc.numberProchainsMessages(
                                (indexMessagesOthers +1) * NB_DISPLAY_MESSAGES,
                                NB_DISPLAY_MESSAGES, numUser,
                                dateValueOthers1, null) == DAOMessage.MESSAGES_YET) {

                    indexMessagesOthers++;

                    afficheAndFillMessages(othersMessages, indexMessagesOthers * NB_DISPLAY_MESSAGES,
                            NB_DISPLAY_MESSAGES, numUser, areaOthers,
                            dateValueOthers1, null);
                } else if (dateValueOthersMin == null
                        && dateValueOthersMax != null
                        // Juste la dateValueMax a été renseignée lors du
                        // dernier appui sur le bouton
                        && rc.numberProchainsMessages(
                                (indexMessagesOthers +1) * NB_DISPLAY_MESSAGES,
                                NB_DISPLAY_MESSAGES, numUser,
                                null, dateValueOthers2) == DAOMessage.MESSAGES_YET) {

                    indexMessagesOthers++;

                    afficheAndFillMessages(othersMessages, indexMessagesOthers * NB_DISPLAY_MESSAGES,
                            NB_DISPLAY_MESSAGES, numUser, areaOthers,
                            null, dateValueOthers2);
                }
            }
        } catch (NotBoundException ex) {
            new JDError("Problème de communication serveur. Exit");
            logger.error("JFClientConnecte.traiteBoutonSuivant() : NotBoundException");
            dispose();
        } catch (RemoteException ex) {
            new JDError("Problème de communication serveur. Exit");
            logger.error("JFClientConnecte.traiteBoutonSuivant() : RemoteException");
            dispose();
        }
    }
    
    /**
     * Si appui sur le bouton de date
     */
    public void traiteBoutonDate() {
        if (! dateField1.getText().trim().equals("")
                && ! dateField2.getText().trim().equals("")) {
            SimpleDateFormat d = new SimpleDateFormat("dd/MM/yyyy");

            try {
                java.util.Date d1 = d.parse(dateField1.getText().trim());
                java.util.Date d2 = d.parse(dateField2.getText().trim());

                if (d1.after(d2)) {
                    new JDError("La 1ère date doit être inférieure ou "
                            + "égale à la 2ème !");
                } else {

                    // On met à jour les messages en fonction
                    // de l'onglet choisi
                    // Mes messages
                    if (onglet.getSelectedIndex() == 0) {

                        // On sauvegarde les dates entrées
                        dateValueMe1 = dateField1.getText().trim();
                        dateValueMe2 = dateField2.getText().trim();

                        indexMessagesMe = 0;

                        if (dateValueMe1.equals("")
                                && dateValueMe2.equals("")) {

                            dateValueMeMin = null;
                            dateValueMeMax = null;

                            // Aucune des 2 dates n'est renseignée,
                            // on charge tous les messages
                            // Affiche les 5 premiers messages me correspondant
                            // à partir du 1er message
                            afficheAndFillMessages(myMessages, indexMessagesMe,
                                    NB_DISPLAY_MESSAGES, myId, areaMe);

                        } else if (dateValueMe1.equals("")
                                && ! dateValueMe2.equals("")) {

                            dateValueMeMin = null;
                            dateValueMeMax = dateField2.getText().trim();

                            afficheAndFillMessages(myMessages, indexMessagesMe,
                                    NB_DISPLAY_MESSAGES, myId, areaMe,
                                    dateValueMeMin, dateValueMeMax);

                        } else if (! dateValueMe1.equals("")
                                && dateValueMe2.equals("")) {

                            dateValueMeMin = dateField1.getText().trim();
                            dateValueMeMax = null;

                            afficheAndFillMessages(myMessages, indexMessagesMe,
                                    NB_DISPLAY_MESSAGES, myId, areaMe,
                                    dateValueMeMin, dateValueMeMax);

                        } else { // Les 2 sont renseignées

                            // On sauvegarde les dates
                            dateValueMeMin = dateValueMe1;
                            dateValueMeMax = dateValueMe2;

                            afficheAndFillMessages(myMessages, indexMessagesMe,
                                    NB_DISPLAY_MESSAGES, myId, areaMe,
                                    dateValueMeMin, dateValueMeMax);
                        }
                    } else if (onglet.getSelectedIndex() == 1) {
                        // Les autres utilisateurs

                        if (list.getSelectedValue() != null) {
                            indexMessagesOthers = 0;

                            // On sauvegarde les dates entrées
                            dateValueOthers1 = dateField1.getText().trim();
                            dateValueOthers2 = dateField2.getText().trim();

                            int numUser = getNumUserSelectedJList();

                            if (dateValueOthers1.equals("")
                                    && dateValueOthers2.equals("")) {

                                dateValueOthersMin = null;
                                dateValueOthersMax = null;

                                // Aucune des 2 dates n'est renseignée,
                                // on charge tous les messages
                                // Affiche les 5 premiers messages me correspondant
                                // à partir du 1er message
                                afficheAndFillMessages(othersMessages, indexMessagesOthers,
                                        NB_DISPLAY_MESSAGES, numUser, areaOthers);

                            } else if (dateValueOthers1.equals("")
                                    && ! dateValueOthers2.equals("")) {

                                dateValueOthersMin = null;
                                dateValueOthersMax = dateField2.getText().trim();

                                afficheAndFillMessages(othersMessages, indexMessagesOthers,
                                        NB_DISPLAY_MESSAGES, numUser,
                                        areaOthers, dateValueOthersMin, dateValueOthersMax);

                            } else if (! dateValueOthers1.equals("")
                                    && dateValueOthers2.equals("")) {

                                dateValueOthersMin = dateField1.getText().trim();
                                dateValueOthersMax = null;

                                afficheAndFillMessages(othersMessages, indexMessagesOthers,
                                        NB_DISPLAY_MESSAGES, numUser,
                                        areaOthers, dateValueOthersMin, dateValueOthersMax);
                            } else { // Les 2 sont renseignées

                                // On sauvegarde les dates
                                dateValueOthersMin = dateValueOthers1;
                                dateValueOthersMax = dateValueOthers2;

                                afficheAndFillMessages(othersMessages, indexMessagesOthers,
                                        NB_DISPLAY_MESSAGES, numUser,
                                        areaOthers, dateValueOthersMin, dateValueOthersMax);
                            }
                        } else {
                            dateField1.setText("");
                            dateField2.setText("");

                            dateValueOthers1 = "";
                            dateValueOthers2 = "";
                        }
                    }
                }
            } catch (ParseException ex) {
                logger.error("JFClientConnecte.traiteBoutonDate() : ParseException");
            }
        } else {
            // On met à jour les messages en fonction
            // de l'onglet choisi
            // Mes messages
            if (onglet.getSelectedIndex() == 0) {

                // On sauvegarde les dates entrées
                dateValueMe1 = dateField1.getText().trim();
                dateValueMe2 = dateField2.getText().trim();

                indexMessagesMe = 0;

                if (dateValueMe1.equals("")
                        && dateValueMe2.equals("")) {

                    dateValueMeMin = null;
                    dateValueMeMax = null;

                    // Aucune des 2 dates n'est renseignée,
                    // on charge tous les messages
                    // Affiche les 5 premiers messages me correspondant
                    // à partir du 1er message
                    afficheAndFillMessages(myMessages, indexMessagesMe,
                            NB_DISPLAY_MESSAGES, myId, areaMe);

                } else if (dateValueMe1.equals("")
                        && ! dateValueMe2.equals("")) {

                    dateValueMeMin = null;
                    dateValueMeMax = dateField2.getText().trim();

                    afficheAndFillMessages(myMessages, indexMessagesMe,
                            NB_DISPLAY_MESSAGES, myId, areaMe,
                            dateValueMeMin, dateValueMeMax);

                } else if (! dateValueMe1.equals("")
                        && dateValueMe2.equals("")) {

                    dateValueMeMin = dateField1.getText().trim();
                    dateValueMeMax = null;

                    afficheAndFillMessages(myMessages, indexMessagesMe,
                            NB_DISPLAY_MESSAGES, myId, areaMe,
                            dateValueMeMin, dateValueMeMax);

                } else { // Les 2 sont renseignées

                    // On sauvegarde les dates
                    dateValueMeMin = dateValueMe1;
                    dateValueMeMax = dateValueMe2;

                    afficheAndFillMessages(myMessages, indexMessagesMe,
                            NB_DISPLAY_MESSAGES, myId, areaMe,
                            dateValueMeMin, dateValueMeMax);
                }
            } else if (onglet.getSelectedIndex() == 1) {
                // Les autres utilisateurs

                if (list.getSelectedValue() != null) {
                    indexMessagesOthers = 0;

                    // On sauvegarde les dates entrées
                    dateValueOthers1 = dateField1.getText().trim();
                    dateValueOthers2 = dateField2.getText().trim();

                    int numUser = getNumUserSelectedJList();

                    if (dateValueOthers1.equals("")
                            && dateValueOthers2.equals("")) {

                        dateValueOthersMin = null;
                        dateValueOthersMax = null;

                        // Aucune des 2 dates n'est renseignée,
                        // on charge tous les messages
                        // Affiche les 5 premiers messages me correspondant
                        // à partir du 1er message
                        afficheAndFillMessages(othersMessages, indexMessagesOthers,
                                NB_DISPLAY_MESSAGES, numUser, areaOthers);

                    } else if (dateValueOthers1.equals("")
                            && ! dateValueOthers2.equals("")) {

                        dateValueOthersMin = null;
                        dateValueOthersMax = dateField2.getText().trim();

                        afficheAndFillMessages(othersMessages, indexMessagesOthers,
                                NB_DISPLAY_MESSAGES, numUser,
                                areaOthers, dateValueOthersMin, dateValueOthersMax);

                    } else if (! dateValueOthers1.equals("")
                            && dateValueOthers2.equals("")) {

                        dateValueOthersMin = dateField1.getText().trim();
                        dateValueOthersMax = null;

                        afficheAndFillMessages(othersMessages, indexMessagesOthers,
                                NB_DISPLAY_MESSAGES, numUser,
                                areaOthers, dateValueOthersMin, dateValueOthersMax);
                    } else { // Les 2 sont renseignées

                        // On sauvegarde les dates
                        dateValueOthersMin = dateValueOthers1;
                        dateValueOthersMax = dateValueOthers2;

                        afficheAndFillMessages(othersMessages, indexMessagesOthers,
                                NB_DISPLAY_MESSAGES, numUser,
                                areaOthers, dateValueOthersMin, dateValueOthersMax);
                    }
                } else {
                    dateField1.setText("");
                    dateField2.setText("");

                    dateValueOthers1 = "";
                    dateValueOthers2 = "";
                }
            }
        }
    }

    /**
     * Quand on clique sur un utilisateur
     */
    @Override
    public void mouseClicked(MouseEvent ev) {
        // Si la liste n'est pas vide ou si on clique sur
        // un élément de la JList non null
        if (list.getSelectedValue() != null) {
            // On change le label au dessus de l'onglet
            // Messages affichés par + pseudo
            if (onglet.getTitleAt(
                    onglet.getSelectedIndex()).equals(
                            "Autres utilisateurs")) {
                panelDroite.setBorder(BorderFactory.createCompoundBorder
                        (BorderFactory.createTitledBorder
                                (MSG_ECRIT_PAR + list.getSelectedValue()),
                                BorderFactory.createEmptyBorder(1, 1, 1, 1)));
            }

            // Si sélection d'un élément de la JList
            // avec un clic droit
            // TODO-FIX : Le JPopupMenu ne suit pas le scroll !!
            if (ev.getButton() == MouseEvent.BUTTON3) {
                int index = list.locationToIndex(ev.getPoint());
                list.setSelectedIndex(index);
                menuList.show(scroll, ev.getX(), ev.getY());
            } else if (ev.getButton() == MouseEvent.BUTTON1) {
                // Clic gauche
                // On va chercher ses messages et on les met
                // dans otherMessages puis on les affiche
                // dans areaOther

                // On RAZ l'index
                indexMessagesOthers = 0;
                dateValueOthers1 = "";
                dateValueOthers2 = "";
                dateValueOthersMin = null;
                dateValueOthersMax = null;

                // On récupère le numUtilisateur sur la personne
                // de la JList qui est sélectionnée
                int numUser = getNumUserSelectedJList();

                // On affiche les messages
                afficheAndFillMessages(othersMessages, indexMessagesOthers,
                        NB_DISPLAY_MESSAGES, numUser, areaOthers);
            }
        }
    }

    @Override
    public void mouseEntered(MouseEvent arg0) {

    }

    @Override
    public void mouseExited(MouseEvent arg0) {

    }

    @Override
    public void mousePressed(MouseEvent arg0) {

    }

    @Override
    public void mouseReleased(MouseEvent arg0) {

    }
}